package com.jifeng.api.wxpay.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jifeng.api.crud.constant.FieldConstant;
import com.jifeng.api.crud.entity.*;
import com.jifeng.api.crud.service.*;
import com.jifeng.api.utils.HttpUtils;
import com.jifeng.api.wxpay.sdk.HttpKit;
import com.jifeng.api.wxpay.sdk.PaymentKit;
import com.jifeng.api.wxpay.service.WXPayNotifyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

@Service("wXPayNotifyService")
@Slf4j
public class WXPayNotifyImpl implements WXPayNotifyService {

    /**
     * 成功的标识
     */
    private final static String SUCCESS = "SUCCESS";

    /**
     * 返回状态码的变量名
     */
    private final static String RETURN_CODE = "return_code";

    public String getRequestUrl() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest().getRequestURI();
    }

    @Autowired
    OrderService orderService;

    @Autowired
    FeeLogService feeLogService;

    @Autowired
    TerminalService terminalService;

    @Autowired
    DeviceService deviceService;

    @Override
    public void startNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("进入微信小程序支付回调");
        String xmlMsg = HttpKit.readData(request);
        log.info("微信小程序通知信息：\n{}" + xmlMsg);
        Map<String, String> resultMap = PaymentKit.xmlToMap(xmlMsg);
        if (resultMap.get(RETURN_CODE).equals(SUCCESS)) {
            String orderNo = resultMap.get("out_trade_no");
//            String attach = resultMap.get("attach");
//            log.info("微信小程序支付成功,附加参数{}", attach);
            String totalFee = resultMap.get("total_fee");
            log.info("微信小程序支付成功,订单号{}", orderNo);

            /**
             * 往支付日志表中插入数据
             */
            FeeLogEntity feeLogEntity = new FeeLogEntity();
            feeLogEntity.setOrderId(Long.parseLong(orderNo));
            feeLogEntity.setFee(Integer.parseInt(totalFee));
            feeLogEntity.setPaidFee(Integer.parseInt(totalFee));
            feeLogEntity.setMemo("支付成功");
            boolean saveRs = feeLogService.save(feeLogEntity);
            if (!saveRs) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "支付日志保存失败");
            }

            /**
             * 判断订单状态是否是调用中状态，如果不是则退出
             */
            OrderEntity orderEntity = orderService.getById(orderNo);
            Integer comState = orderEntity.getComState();
            if (comState != 3) {
                return;
            }

            /**
             *  通过订单号 修改数据库中的记录
             */
            orderEntity.setComState(4);
            orderEntity.setRevTime(new Date());
            orderEntity.setPaidFee(Integer.parseInt(totalFee));
            orderEntity.setState(4);
            orderEntity.setStartFeeTime(new Date());
            boolean updateOrderRs = orderService.updateById(orderEntity);
            if (!updateOrderRs) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "更新订单失败");
            }

            orderEntity.setComState(7);
            orderEntity.setRevTime(new Date());
            boolean updateOrderRs2 = orderService.updateById(orderEntity);
            if (!updateOrderRs2) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "更新订单失败");
            }

            /**
             * 设置机柜为空闲状态
             */
            TerminalEntity terminalEntity = new TerminalEntity();
            terminalEntity.setRentState(0);
            boolean update = terminalService.update(terminalEntity,new UpdateWrapper<TerminalEntity>().eq(FieldConstant.T_TERMINAL_IOT,orderEntity.getTerminalId()));
            if (!update) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "更新机柜状态失败");
            }

            /**
             * 调用下位机
             */
            boolean rentDeviceRs = HttpUtils.rentDevice(orderEntity.getTerminalId(), "3", orderEntity.getMobile(), orderNo);
            if (!rentDeviceRs) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "设备未连接");
            }
        }
        String result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        try {
            response.getWriter().write(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void endNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("进入欠费支付回调");
        String xmlMsg = HttpKit.readData(request);
//        log.info("欠费支付回调通知信息：\n{}" + xmlMsg);
        Map<String, String> resultMap = PaymentKit.xmlToMap(xmlMsg);
        if (resultMap.get(RETURN_CODE).equals(SUCCESS)) {
            String orderNo = resultMap.get("out_trade_no");
            String totalFee = resultMap.get("total_fee");
            String orderId = resultMap.get("attach");
//            log.info("欠费支付成功,订单号{}", orderNo);

            /**
             * 往支付日志表中插入数据
             */
            FeeLogEntity feeLogEntity = new FeeLogEntity();
            feeLogEntity.setOrderId(Long.parseLong(orderId));
            feeLogEntity.setFee(Integer.parseInt(totalFee));
            feeLogEntity.setPaidFee(Integer.parseInt(totalFee));
            feeLogEntity.setMemo("支付欠费金额成功");
            boolean saveRs = feeLogService.save(feeLogEntity);
            if (!saveRs) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "支付日志保存失败");
            }

            /**
             * 判断订单状态是否是调用中状态，如果不是则退出
             */
            OrderEntity orderEntity = orderService.getById(orderId);
//            OrderEntity orderEntity = orderService.getOne(new QueryWrapper<OrderEntity>().eq(FieldConstant.T_ORDER_NUMBER, orderNo), false);
//            Integer comState = orderEntity.getComState();
//            if (comState != 3) {
//                return;
//            }
//            if (orderEntity==null){
//                log.warn("path：{}，errMsg：{}", getRequestUrl(), "订单不存在");
//            }

            /**
             *  通过订单号 修改数据库中的记录
             */
            orderEntity.setComState(12);
            orderEntity.setState(7);
            orderEntity.setRevTime(new Date());
            orderEntity.setPaidFee(orderEntity.getFee());
            boolean updateOrderRs = orderService.updateById(orderEntity);
            if (!updateOrderRs) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "更新订单失败");
            }

            /**
             * 累加机柜表和设备表的租赁收入
             */
            // TODO: 2020/10/9 待有数据就解开注释
//            TerminalEntity terminalEntity = terminalService.getById(orderEntity.getTerminalId());
//            terminalEntity.setIncome(terminalEntity.getIncome() + orderEntity.getPaidFee());
//            boolean updateTerminalRs = terminalService.updateById(terminalEntity);
//            if (!updateTerminalRs){
//                log.warn("path：{}，errMsg：{}，cause：{}", getRequestUrl(), "累加机柜租金收入失败","传入的机柜编号为空或未找到机柜");
//            }

//            DeviceEntity deviceEntity = deviceService.getById(orderEntity.getDeviceId());
//            deviceEntity.setIncome(deviceEntity.getIncome() + orderEntity.getPaidFee());
//            boolean updateDeviceRs = deviceService.updateById(deviceEntity);
//            if (!updateDeviceRs){
//                log.warn("path：{}，errMsg：{}，cause：{}", getRequestUrl(), "累加设备租金收入失败","传入的设备编号为空或未找到设备");
//            }

            /**
             * 调用下位机
             */
            boolean rentDeviceRs = HttpUtils.rentDevice(orderEntity.getTerminalId(), "2", orderEntity.getMobile(), orderNo);
            if (!rentDeviceRs) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "设备未连接");
            }
        }
        String result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        try {
            response.getWriter().write(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
